﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
namespace eTerm.ASynClientSDK
{
    #region 辅助类
    public class AVHFlight {
        public string FirstLine { get; set; }

        public string SecondLine { get; set; }

        public string SubCabin { get; set; }
    }
    #endregion

    public class AnalysisAVH
    {
        public AnalysisAVH() { }

        private FlightCarbin[] ParseCarbin(string szInfo,string flightNo,string cityPaire,string craftType) 
        {                
            FlightCarbin[] fcs = new FlightCarbin[] { };
            szInfo = Regex.Replace(szInfo, @"[A-Z][#|*!]", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            //szInfo = Regex.Replace(szInfo, @"\s[A-Z0-9]{3,6}\s", string.Empty, RegexOptions.Multiline | RegexOptions.IgnoreCase);
            szInfo = Regex.Replace(szInfo, @"\s{2,}(T[0-9]\s+)+", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            szInfo = Regex.Replace(szInfo, @"\s{2,}\-\-(T[0-9]\s+)+", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            szInfo = Regex.Replace(szInfo, @"\s{2,}(T[0-9]\s+)\-\-", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Multiline);
            szInfo = szInfo.Replace(flightNo, string.Empty);
            szInfo = szInfo.Replace(cityPaire, string.Empty);
            szInfo = szInfo.Replace(craftType, string.Empty);

            MatchCollection M = Regex.Matches(szInfo, @"([A-Z][1-9]?)([A-Z0-9])\s");
            foreach (Match _m in M)
            {
                FlightCarbin fc = new FlightCarbin();
                fc.Carbin = _m.Groups[1].Value;
                fc.Number = _m.Groups[2].Value;
                Array.Resize(ref fcs, fcs.Length + 1);
                fcs[fcs.Length - 1] = fc;
            }
            return fcs;
        }

        private void ParsFlightDetail(Flight flt, string str)
        {
            
            string s = Regex.Match(str, @"\s\d{4}(\+\d)?\s+\d{4}(\+\d)?\s+\w{3}\s+\d(\^|\s)[A-Z]{0,1}\s+(E)?").Value.ToString();
            if (s.Trim().Length > 0)
            { 
                MatchCollection M = Regex.Matches(s,@"\d{4}(\+\d)?");
                if (M.Count > 0)
                    flt.DepartureTime = M[0].Value.ToString();
                if(M.Count>1)
                    flt.ArrivalTime = M[1].Value.ToString();
                flt.AircraftType = Regex.Match(s, @"\s\w{3}\s").Value.ToString().Trim();
                s = Regex.Match(s, @"\s\d(\^)?\s?[A-Z]{0,1}\s+(E)?").Value.ToString();
                flt.Stop = Regex.Match(s, @"\s\d").Value.ToString().Trim();
                flt.Meal = Regex.Match(s, @"\^").Value.ToString();
                M = Regex.Matches(s, @"[A-Z]");
                if (M.Count == 2)
                {
                    flt.FoodType = M[0].Value;
                    flt.E = M[1].Value;
                }
                else if (M.Count == 1)
                {
                    if (M[0].Value.ToString() == "E")
                        flt.E = M[0].Value.ToString();
                    else
                        flt.FoodType = M[0].Value;
                }
            }
        }

        private Flight GetByTemp(AVHFlight f)
        {
            Flight r = new Flight() { Carbins = new List<FlightCarbin>() };


            #region 分析航班号
            Match fligntNo = Regex.Match(f.FirstLine, @"\b\d(\-|\+){0,1}\s{1,}(\*){0,1}((\w{2})(\d{2,4}))\s+([A-Z]{2}){0,1}(!|\*|\#){0,1}\s", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            if (!fligntNo.Success) return null;
            r.FlightNO = fligntNo.Groups[5].Value;
            r.Airline = fligntNo.Groups[4].Value;
            if (fligntNo.Groups[2].Value == @"*")
                r.CodeShare = true;

            #endregion

            #region 排序9C航班
            if (Regex.IsMatch(r.Airline, @"9C", RegexOptions.IgnoreCase | RegexOptions.Multiline)) return null;
            #endregion


            #region 其它参数
            Match other = Regex.Match(f.FirstLine, @"\s(([A-Z]{3}){2})\s(((\d{4})((\s+\+1)?)\s+)+)\s+(\w*)\s(0|1)([\^\s]?)([A-Z]|\s)", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            if (other.Success)
            {
                r.DepartureAirport = other.Groups[2].Captures[0].Value;
                r.ArrivalAirport = other.Groups[2].Captures[1].Value;
                r.DepartureTime = other.Groups[5].Captures[0].Value;
                r.ArrivalTime = other.Groups[5].Captures[1].Value;
                r.AircraftType = other.Groups[8].Value;
                r.Stop = other.Groups[9].Value;
                r.Meal = other.Groups[11].Value;
                r.FoodType=other.Groups[11].Value;
            }
            else { return null; }
            #endregion

            #region 分析主舱位
            Match mainCabin = Regex.Match(f.FirstLine, @"\s(([A-Z][0-9A-Z]\s)+)", RegexOptions.IgnoreCase | RegexOptions.Multiline);
            if (!mainCabin.Success) return r;
            foreach (Capture g in mainCabin.Groups[2].Captures)
            {
                if (!Regex.IsMatch(g.Value.Trim(), @"[1-9A]$", RegexOptions.IgnoreCase | RegexOptions.Multiline)) continue;
                r.Carbins.Add(new FlightCarbin()
                {
                    Carbin = g.Value.Substring(0, 1),
                    Number = g.Value.Substring(1, 1)
                });
            }
            #endregion

            #region 分析低价舱位
            Match subCabin = Regex.Match(f.SecondLine, @"\>\s+(((\w{2})(\d{2,4}))?)\s+(([A-Z][0-9A-Z]\s)+)\s+((((T\d)|[A-Z]|\-{2})\s+)+([0-9\:]+)){0,}", RegexOptions.Multiline | RegexOptions.IgnoreCase);
            if (subCabin.Success)
            {
                foreach (Capture g in subCabin.Groups[6].Captures)
                {
                    if (!Regex.IsMatch(g.Value.Trim(), @"[1-9A]$", RegexOptions.IgnoreCase | RegexOptions.Multiline)) continue;
                    r.Carbins.Add(new FlightCarbin()
                    {
                        Carbin = g.Value.Substring(0, 1),
                        Number = g.Value.Substring(1, 1)
                    });
                }


                #region 分析航站楼及飞行时间
                if (subCabin.Groups[9].Success)
                {
                    r.DepartTerminal = subCabin.Groups[9].Captures[0].Value;
                    r.ArrivalTerminal = subCabin.Groups[9].Captures[1].Value;
                    r.RunTimeDuration = subCabin.Groups[11].Value;
                }
                #endregion
            }
            #endregion


            #region 分析子舱位

            #endregion

            return r;
        }

        private Flight ParseFlight(string szInfo)
        {
            MatchCollection matches = Regex.Matches(szInfo, @"\b\d(\-|\+){0,1}\s{1,}(\*){0,1}\w{2}\d{2,4}\s+([A-Z]{2}){0,1}(!|\*|#){0,1}\s([A-Z]\w\s){1,}\s+[A-Z]{6}\s+\d{4}(\+\d){0,}\s+\d{4}(\+\d){0,}\s+\w{3}\s+\d(\^|\s)\w{0,1}\s+(E){0,1}\s{0,}(>){0,1}\s+(\w{2}\d{2,4}){0,1}\s+([A-Z]\w\s){0,}");
            foreach (Match _m in matches)
            {
                string a = _m.Value.ToString();
                if (Regex.IsMatch(a, @"\s9C\d{3,4}\s"))
                {
                    szInfo = szInfo.Replace(a, "");
                    break;
                }
            }
            if (szInfo.Trim() == "")
                return null;
            Flight flt = new Flight();
            string str = Regex.Match(szInfo, @"\b\d(\-|\+){0,1}\s+(\*){0,1}\w{2}\d{2,4}").Value;
            str = Regex.Match(str, @"(\*){0,1}\w{2}\d{2,4}").Value;
                            
            if (str.Trim().Length == 0)
            { return null; }
            else
            {
                if (str[0] == '*')
                {
                    flt.CodeShare = true;
                    str = str.Substring(1);
                }
                flt.Airline = str.Substring(0, 2);
                flt.FlightNO = str.Substring(2);
                if (flt.FlightNO.EndsWith(@"1589")) {
                    Console.WriteLine();
                }
            }
            str = Regex.Match(szInfo, @"\b\d(\-|\+){0,1}\s{1,}(\*){0,1}\w{2}\d{2,4}\s+([A-Z]{2}){0,1}(!|\*|\#){0,1}\s([A-Z]\w\s){1,}\s+[A-Z]{6}\s+\d{4}(\+\d){0,}\s+\d{4}(\+\d){0,}\s+\w{3}\s+\d(\^|\s)\w{0,1}\s+(E){0,1}\s{0,}(>){0,1}\s+(\w{2}\d{2,4}){0,1}\s+([A-Z]\w\s){0,}([A-Z0-9:\s]+)((\*+)\s+([A-Z][1-9][1-9A-Z]\s?)+)?").Value;
            if (str.Trim().Length == 0)
            { return null; }

            if (flt.FlightNO == @"9378")
                Console.Write(flt.FlightNO);


            if (flt.CodeShare)
            {
                flt.CodeShareFlight = Regex.Match(Regex.Match(szInfo, @">\s+\w{2}\d{2,4}").Value, @"\w{2}\d{2,4}").Value;
            }
            flt.DepartureAirport = Regex.Match(str, @"\s[A-Z]{6}\s").Value.Trim().Substring(0, 3);
            flt.ArrivalAirport = Regex.Match(str, @"\s[A-Z]{6}\s").Value.Trim().Substring(3);

            ParsFlightDetail(flt, str);

            FlightCarbin[] fcs = ParseCarbin(str, string.Format(@"{0}{1}", flt.Airline, flt.FlightNO), string.Format(@"{0}{1}", flt.DepartureAirport, flt.ArrivalAirport), flt.AircraftType);

            //flt.Carbins = fcs;



            str = Regex.Replace(szInfo, @"\b\d(\-|\+){0,1}\s{1,}(\*){0,1}\w{2}\d{2,4}\s+([A-Z]{2}){0,1}(!|\*|\#){0,1}\s([A-Z]\w\s){1,}\s+[A-Z]{6}\s+\d{4}(\+\d){0,}\s+\d{4}(\+\d){0,}\s+\w{3}\s+\d(\^|\s)\w{0,1}\s+(E){0,1}\s{0,}(>){0,1}\s+(\w{2}\d{2,4}){0,1}\s+([A-Z]\w\s){0,}([A-Z0-9:\s]+)((\*+)\s+([A-Z][1-9][1-9A-Z]\s?)+)?", "");
            
            //flt.SubFlight = ParseSubFlight(str);
            return flt;
        }

        private Flight[] ParseSubFlight(string szInfo)
        {
            Flight[] flts = new Flight[] { };
            MatchCollection M = Regex.Matches(szInfo, @"(\*){0,1}\w{2}\d{2,4}\s+([A-Z]{2}){0,1}(!|\*|#){0,1}\s([A-Z]\w\s){1,}\s+[A-Z]{3}\s+\d{4}(\+\d){0,}\s+\d{4}(\+\d){0,}\s+\w{3}\s+\d(\^|\s)\w{0,1}\s+(E){0,1}\s{0,}(>){0,1}\s+(\w{2}\d{2,4}){0,1}\s+([A-Z]\w\s){0,}");
            foreach (Match _m in M)
            {
                Flight flt = new Flight();
                string str = Regex.Match(_m.Value, @"(\*){0,1}\w{2}\d{2,4}\s+([A-Z]{2}){0,1}(!|\*|#){0,1}\s([A-Z]\w\s){1,}\s+[A-Z]{3}\s").Value.Trim();

                if (str.Trim().Length == 0)
                { }
                else
                {
                    if (str[0] == '*')
                    {
                        flt.CodeShare = true;
                        str = str.Substring(1);
                    }
                    flt.Airline = Regex.Match(str, @"\w{2}\d{2,4}\s").Value.ToString().Substring(0, 2);
                    flt.FlightNO = Regex.Match(str, @"\w{2}\d{2,4}\s").Value.ToString().Substring(2).Trim();
                }

                flt.DepartureAirport = "";
                flt.ArrivalAirport = Regex.Match(str, @"\s[A-Z]{3}").Value.Trim();
                str = _m.Value.Trim();
                FlightCarbin[] fcs = ParseCarbin(str, string.Format(@"{0}{1}", flt.Airline, flt.FlightNO), string.Format(@"{0}{1}", flt.DepartureAirport, flt.ArrivalAirport),string.Empty);
                //flt.Carbins = fcs;
                if (flt.CodeShare)
                {
                    flt.CodeShareFlight = Regex.Match(Regex.Match(str, @">\s+\w{2}\d{2,4}").Value, @"\w{2}\d{2,4}").Value;
                }
                Array.Resize(ref flts, flts.Length + 1);
                flts[flts.Length - 1] = flt;
            }
            return flts;
        }

        public FlightData ParseAVH(string szCmd, string szResult)
        {
            string[] s = new string[]{};
            List<AVHFlight> rtVal = new List<AVHFlight>();
            FlightData fd = new FlightData();
            
            Flight[] flts = new Flight[] { };
            s= szResult.Trim().Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            
            #region 还原成辅助类集合
            int index = 0;
            s.ToList().ForEach(t =>
            {
                AVHFlight f = new AVHFlight();
                if (Regex.IsMatch(t, @"\b\d(\-|\+){0,1}\s{1,}(\*){0,1}\w{2}\d{2,4}", RegexOptions.IgnoreCase | RegexOptions.Multiline))     //航班首行
                {
                    f.FirstLine = t;
                    f.SecondLine = s[index + 1];
                    if (s.Length > index + 2 && Regex.IsMatch(s[index + 2], @"^\s+\*{2}\s+([A-Z]\d[A-Z](\s))+", RegexOptions.IgnoreCase | RegexOptions.Multiline))
                    {
                        f.SubCabin = s[index + 2];
                    }

                }

                if (!string.IsNullOrEmpty(f.FirstLine))
                    rtVal.Add(f);
                index++;
            });
            #endregion

            #region 通过辅助类分析航班
            fd.Flights = new List<Flight>();
            foreach (AVHFlight v in rtVal)
            {
                try
                {
                    Flight x = GetByTemp(v);
                    if (x == null) continue;
                    fd.Flights.Add(x);
                }
                catch { }
            }
            #endregion

            
            return fd;
        }
    }
}
